package com.iddaa.core.aspect;

import java.io.IOException;
import java.net.InetSocketAddress;

import net.spy.memcached.MemcachedClient;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import com.iddaa.core.annotation.Memcached;
import com.iddaa.core.annotation.MemcachedRead;

@Aspect
@Component("memcacheAspect")
public class MemcachedAspect {

	private MemcachedClient memcachedClient;

	private static final Logger logger = LoggerFactory.getLogger(MemcachedAspect.class);

	public MemcachedAspect() {

		try {
			memcachedClient = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private String getkey(Memcached memcached, Long id) {
		return memcached.prefix() + ":" + id;
	}

	@Around(value = "@annotation(memcachedRead)")
	public Object readMemcached(ProceedingJoinPoint joinPoint, MemcachedRead memcachedRead) {
		try {
			StopWatch stopWatch = new StopWatch();
			stopWatch.start();

			Memcached memcached = joinPoint.getTarget().getClass().getAnnotation(Memcached.class);
			String key = getkey(memcached, Long.parseLong(joinPoint.getArgs()[0].toString()));// get
			Object object = memcachedClient.get(key);// try to get the object
			if (object == null) {// if the object is not in the cache...
				object = joinPoint.proceed();// ..get the object from the
				memcachedClient.set(key, memcached.expiration(), object);// ...write
			}
			stopWatch.stop();
			logger.info("Returning from {} memcache at {} ms", key, stopWatch.getTotalTimeMillis());
			return object;
		} catch (Throwable e) {
			throw new RuntimeException(e);
		}
	}
}
